Skip to content

Conversation

daymxn
Copy link
Member

@daymxn daymxn commented Oct 8, 2025

This PR adds Integration tests for the Live API.

The tests currently test the following:

  • Text - Text
  • Text - Audio
  • Audio - Audio
  • Audio - Text
  • Function Calling
  • Function Cancellation
  • Interruption
  • Incremental (just that it works)

Test are written via the swift testing framework (matching our other [newer] integration tests), and are parametrized to run across both backends and different services. I've removed the global variants of the parameters though, as the vertex model only supports us-central1 anyhow.

#no-changelog

@daymxn daymxn self-assigned this Oct 8, 2025
@daymxn daymxn changed the title chore(ai): Add tests chore(ai): Add tests for Live API Oct 8, 2025
Copy link
Contributor

@andrewheard andrewheard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend splitting off the unit tests into a separate PR. They LGTM.

@daymxn
Copy link
Member Author

daymxn commented Oct 10, 2025

I'd recommend splitting off the unit tests into a separate PR. They LGTM.

@andrewheard Oh I already intended to do this (see the PR description for reference). I just have everything here for my own centralization purposes, until I split them off.

@daymxn daymxn changed the title chore(ai): Add tests for Live API chore(ai): Add integration tests for Live API Oct 10, 2025
@daymxn daymxn marked this pull request as ready for review October 10, 2025 22:46
import SwiftUI
import Testing

@testable import struct FirebaseAI.APIConfig
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice making tightly scoped testable imports 👍


@Suite(.serialized)
struct LiveSessionTests {
private let OneSecondInNanoseconds = UInt64(1e+9)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use lower camelcase for properties

Suggested change
private let OneSecondInNanoseconds = UInt64(1e+9)
private let oneSecondInNanoseconds = UInt64(1e+9)

outputAudioTranscription: AudioTranscriptionConfig()
)

private enum systemInstructions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: use upper camelcase for enum type definitions

Suggested change
private enum systemInstructions {
private enum SystemInstructions {

return
}
await session.sendAudioRealtime(audioFile.data)
await session.sendAudioRealtime(Data(repeating: 0, count: audioFile.data.count))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of doing this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is received as silence to make the session end?

await session.sendTextRealtime("Alex")

guard let toolCall = try await session.collectNextToolCall() else {
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be preceded with an issue recording?

Something like–

Suggested change
return
Issue.record("Incomplete tool call.")
return


#expect(functionCall.name == "getLastName")
guard let response = getLastName(args: functionCall.args) else {
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be preceded with an issue recording?

Something like–

Suggested change
return
Issue.record("Incomplete tool call.")
return

await session.sendTextRealtime("Alex")

guard let toolCall = try await session.collectNextToolCall() else {
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like above, does this need an issue recording before the return?

await session.sendAudioRealtime(Data(repeating: 0, count: audioFile.data.count))

// wait a second to allow the model to start generating (and cuase a proper interruption)
try await Task.sleep(nanoseconds: OneSecondInNanoseconds)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
try await Task.sleep(nanoseconds: OneSecondInNanoseconds)
try await Task.sleep(nanoseconds: oneSecondInNanoseconds)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants